package com.spt.ws.ctrl;


import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.google.gson.Gson;
import com.spt.ws.dao.ITaskService;
import com.spt.ws.task.QuartzTaskFactory;
import com.spt.ws.tasks.ITask;

import java.text.SimpleDateFormat;


@Controller
@RequestMapping("/manage")
public class ImanageCtrl {
    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    @Autowired
    private ITaskService taskService;
    
	
    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    private static Logger log = LogManager.getLogger("com.spt.ws.man");


	private static final Gson gson = new Gson();

	@RequestMapping(value = "/query")
	//@RequiresRoles(value={"USER","ADMIN"},logical=Logical.OR)
	//@RequiresUser
	@RequiresUser
	public @ResponseBody String query(HttpServletRequest req, Model model)  {
		Map<String,Object> out = new HashMap<String, Object>();
		try{
		    List<Map<String, Object>> li = taskService.getAllTask();
    		Scheduler scheduler = schedulerFactoryBean.getScheduler();
    		Date tmpDate = null;
    		String tmpDateStr = null;
		
    		for(Map<String, Object> task : li){
    		    TriggerKey triggerKey = TriggerKey.triggerKey((String)task.get("TASKID"), (String)task.get("GROUPID"));    
    	        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
    	        if(trigger == null) {
    	            task.put("R_STATUS", "NOT IN USE");
    	            continue;
    	        }
    	        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
    	        task.put("R_STATUS", triggerState.name());
    	        tmpDate = trigger.getNextFireTime();
    	        if(tmpDate == null) {
    	            tmpDateStr = "";
    	        }else{
    	            tmpDateStr = df.format(tmpDate);
    	        }
    	        task.put("R_NEXTFIRETIME",tmpDateStr);
    	        tmpDate = trigger.getPreviousFireTime();
    	        if(tmpDate == null) {
                    tmpDateStr = "";
                }else{
                    tmpDateStr = df.format(tmpDate);
                }
    	        task.put("R_PREFIRETIME",tmpDateStr);
    	        tmpDate = trigger.getStartTime();
    	        if(tmpDate == null) {
                    tmpDateStr = "";
                }else{
                    tmpDateStr = df.format(tmpDate);
                }
    	        task.put("R_STARTTIME", tmpDateStr);
    	        tmpDate = trigger.getEndTime();
    	        if(tmpDate == null) {
                    tmpDateStr = "";
                }else{
                    tmpDateStr = df.format(tmpDate);
                }
    	        task.put("R_ENDTIME", tmpDateStr);
    		}
    		out.put("code", "0");
    		out.put("data", li);
		}catch(Exception e){
		    log.error(e.getMessage());
		    out.put("code", "-1");
            out.put("message", "读取进程状态失败");
		}
		return gson.toJson(out);
	}
	
	@RequestMapping(value = "/stopTask")
	@RequiresUser
	//@RequiresRoles(value={"ADMIN"},logical=Logical.OR)
    public @ResponseBody String stop(HttpServletRequest req, Model model) {
        Map<String,Object> out = new HashMap<String, Object>();
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        String rowStr = req.getParameter("row");
        Map<String,String> task = gson.fromJson(rowStr, Map.class);
        //String groupID = req.getParameter("groupid");
        JobKey jobKey = JobKey.jobKey(task.get("TASKID"), task.get("GROUPID"));
        try {
            scheduler.deleteJob(jobKey);
            taskService.setLastStatus(task.get("ID"),"n");
            out.put("code", "0");
            out.put("message", "成功停止 " + task.get("TASKID") + " 任务");
        } catch (SchedulerException e) {
            log.error(e.getMessage());
            out.put("code", "-1");
            out.put("message", "停止任务失败");
        } 
        return gson.toJson(out);
    }
	
	@RequestMapping(value = "/startTask")
	@RequiresUser
	public @ResponseBody String start(HttpServletRequest req, Model model) {
        Map<String,Object> out = new HashMap<String, Object>();
        String rowStr = req.getParameter("row");
        Map<String,String> task = gson.fromJson(rowStr, Map.class);
        //String groupID = req.getParameter("groupid");
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey((String)task.get("TASKID"), (String)task.get("GROUPID"));
        CronTrigger trigger;
        try {
            trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
         // 不存在，创建一个
            if (null == trigger) {
                JobDetail jobDetail = JobBuilder.newJob(QuartzTaskFactory.class)
                        .withIdentity((String) task.get("TASKID"), (String) task.get("GROUPID")).build();
                jobDetail.getJobDataMap().put("scheduleJob", task);
                // 表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule((String) task.get("CRON"));
                // 按新的表达式构建一个新的trigger
                trigger = TriggerBuilder.newTrigger()
                        .withIdentity((String) task.get("TASKID"), (String) task.get("GROUPID"))
                        .withSchedule(scheduleBuilder).build();
                scheduler.scheduleJob(jobDetail, trigger);
                taskService.setLastStatus(task.get("ID"),"y");
            } else {
                // trigger已存在，则更新相应的定时设置
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule((String) task.get("CRON"));
                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
            out.put("code", "0");
            out.put("message", "成功启动 " + task.get("TASKID") + " 任务");
        } catch (Exception e) {
            log.error(e.getMessage());
            out.put("code", "-1");
            out.put("message", "启动任务失败");
        }
        
        
        return gson.toJson(out);
    }
	
	@RequestMapping(value = "/modifyTask")
	@RequiresUser
    public @ResponseBody String modify(HttpServletRequest req, Model model) {
        String insertRows = req.getParameter("insertrows");
        String deleteRows = req.getParameter("deleterows");
        String modifytRows = req.getParameter("modifyrows");
        Map<String,Object> out = new HashMap<String, Object>();
        String messager = "";
        if(insertRows != null ){
            List<Map<String, String>> li = gson.fromJson(insertRows, List.class);
            if(li.size()>0){
                for(Map<String, String> params : li){
                    try {
                        taskService.addTask(params);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        messager += "失败信息：taskid " + params.get("TASKID") + ", groupid " + params.get("GROUPID") + "插表失败。<br>";
                    }
                }
            }
        }
        if(modifytRows != null ){
            List<Map<String, String>> li = gson.fromJson(modifytRows, List.class);
            if(li.size()>0){
                for(Map<String, String> params : li){
                    try {
                        taskService.modifyTask(params);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error(e.getMessage());
                        messager += "失败信息：taskid " + params.get("TASKID") + ", groupid " + params.get("GROUPID") + "更新失败。<br>";
                    }
                }
            }
        }
        
        if(deleteRows != null ){
            List<Map<String, String>> li = gson.fromJson(deleteRows, List.class);
            if(li.size()>0){
                for(Map<String, String> params : li){
                    try {
                        taskService.removeTask(params.get("ID"));
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error(e.getMessage());
                        messager += "失败信息：taskid " + params.get("TASKID") + ", groupid " + params.get("GROUPID") + "更新失败。<br>";
                    }
                }
            }
        }
        if(messager.length() == 0){
            out.put("code", "0");
        }else{
            out.put("code", "-1");
            out.put("message", messager);
        }
        
        return gson.toJson(out);
    }
	
	@RequestMapping(value = "/doTaskOnce")
	@RequiresUser
    public @ResponseBody String doTaskOnce(HttpServletRequest req, Model model) {
	    Map<String,Object> out = new HashMap<String, Object>();
	    ITask task;
	    String beanName = req.getParameter("bean");
	    WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
        task = (ITask) wac.getBean(beanName);
        try {
            task.doTask();
            out.put("code", "0"); 
        }catch(Exception e) {
            out.put("code", "-1");
            out.put("message", e.getMessage());
        }
        return gson.toJson(out);
    }

	@RequestMapping(value = "/doOne")
	public @ResponseBody String doOne(HttpServletRequest req, Model model) {
		String methodName = req.getParameter("method");
		Map<String,Object> out = new HashMap<String, Object>();
		
		return gson.toJson(out);
	}
	
}
